package com.smartcruise.task;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.BaseAdapter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import io.realm.OrderedRealmCollection;
import io.realm.RealmChangeListener;
import io.realm.RealmList;
import io.realm.RealmModel;
import io.realm.RealmResults;

/**
 * Created by FengChaoQun
 * on 2018/4/11 0011
 */

public abstract class CustomRealmAdapter<T extends RealmModel> extends BaseAdapter {
    @Nullable
    protected OrderedRealmCollection<T> adapterData;
    private final RealmChangeListener<OrderedRealmCollection<T>> listener;
    private List<T> data = new ArrayList<>();

    public CustomRealmAdapter(@Nullable OrderedRealmCollection<T> data) {
        if (data != null && !data.isManaged()) {
            throw new IllegalStateException("Only use this adapter with managed list, for un-managed lists you can just use the BaseAdapter");
        } else {
            this.adapterData = data;
            this.listener = new RealmChangeListener<OrderedRealmCollection<T>>() {
                public void onChange(OrderedRealmCollection<T> results) {
                    CustomRealmAdapter.this.notifyDataSetChanged();
                }
            };
            if (this.isDataValid()) {
                this.addListener(data);
            }

        }
    }

    private void addListener(@NonNull OrderedRealmCollection<T> data) {
        if (data instanceof RealmResults) {
            RealmResults results = (RealmResults) data;
            results.addChangeListener(this.listener);
        } else {
            if (!(data instanceof RealmList)) {
                throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
            }

            RealmList list = (RealmList) data;
            list.addChangeListener(this.listener);
        }

    }

    private void removeListener(@NonNull OrderedRealmCollection<T> data) {
        if (data instanceof RealmResults) {
            RealmResults results = (RealmResults) data;
            results.removeChangeListener(this.listener);
        } else {
            if (!(data instanceof RealmList)) {
                throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
            }

            RealmList list = (RealmList) data;
            list.removeChangeListener(this.listener);
        }

    }

    public int getCount() {
        data.clear();
        if (adapterData != null) {
            data.addAll(adapterData);
            Collections.sort(data, getComparator());
        }
        return this.isDataValid() ? this.adapterData.size() : 0;
    }

    @Nullable
    public T getItem(int position) {
        return this.isDataValid() ? this.data.get(position) : null;
    }

    public long getItemId(int position) {
        return (long) position;
    }

    public void updateData(@Nullable OrderedRealmCollection<T> data) {
        if (this.listener != null) {
            if (this.isDataValid()) {
                this.removeListener(this.adapterData);
            }

            if (data != null && data.isValid()) {
                this.addListener(data);
            }
        }

        this.adapterData = data;
        this.notifyDataSetChanged();
    }

    private boolean isDataValid() {
        return this.adapterData != null && this.adapterData.isValid();
    }

    abstract Comparator<T> getComparator();
}
